package utils

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"

	"gitee.com/liumou_site/go-network-monitoring/types"
)

// ParseNetFile 解析 /proc/net/* 文件
func ParseNetFile(filePath, protocol string) ([]types.ProcessConnection, error) {
	file, err := os.Open(filePath)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	var connections []types.ProcessConnection
	scanner := bufio.NewScanner(file)

	// 跳过标题行
	if scanner.Scan() {
		// 忽略标题行
	}

	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		if line == "" {
			continue
		}

		fields := strings.Fields(line)
		if len(fields) < 10 {
			continue
		}

		// 解析连接信息
		conn, err := ParseConnectionLine(fields, protocol)
		if err != nil {
			continue // 跳过解析失败的行
		}

		connections = append(connections, conn)
	}

	if err := scanner.Err(); err != nil {
		return nil, err
	}

	return connections, nil
}

// ParseConnectionLine 解析连接行信息
func ParseConnectionLine(fields []string, protocol string) (types.ProcessConnection, error) {
	// 字段格式: sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
	if len(fields) < 10 {
		return types.ProcessConnection{}, fmt.Errorf("字段数不足")
	}

	// 解析本地地址和端口
	localAddr, localPort, err := ParseAddress(fields[1])
	if err != nil {
		return types.ProcessConnection{}, fmt.Errorf("解析本地地址失败: %v", err)
	}

	// 解析远程地址和端口
	remoteAddr, remotePort, err := ParseAddress(fields[2])
	if err != nil {
		return types.ProcessConnection{}, fmt.Errorf("解析远程地址失败: %v", err)
	}

	// 解析连接状态
	stateHex := fields[3]
	status := ParseConnectionState(stateHex, protocol)

	// 解析inode
	inode := fields[9]

	return types.ProcessConnection{
		Protocol:      protocol,
		LocalAddr:     localAddr,
		LocalPort:     localPort,
		RemoteAddr:    remoteAddr,
		RemotePort:    remotePort,
		Status:        status,
		Inode:         inode,
		BytesSent:     0,
		BytesRecv:     0,
		SpeedUp:       0,
		SpeedDown:     0,
		BytesSentText: "0 B",
		BytesRecvText: "0 B",
		SpeedUpText:   "0 B/s",
		SpeedDownText: "0 B/s",
	}, nil
}

// ReadProcFile 读取 /proc 文件内容
func ReadProcFile(filePath string) ([]string, error) {
	file, err := os.Open(filePath)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	var lines []string
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		if line != "" {
			lines = append(lines, line)
		}
	}

	return lines, scanner.Err()
}

// ParseProcStatusField 从 /proc/[pid]/status 文件中解析指定字段
func ParseProcStatusField(statusData, fieldName string) (string, error) {
	lines := strings.Split(statusData, "\n")
	for _, line := range lines {
		if strings.HasPrefix(line, fieldName+":") {
			fields := strings.Fields(line)
			if len(fields) > 1 {
				return fields[1], nil
			}
		}
	}
	return "", fmt.Errorf("字段 %s 未找到", fieldName)
}

// ParseHexToUint64 解析十六进制字符串为uint64
func ParseHexToUint64(hexStr string) (uint64, error) {
	return strconv.ParseUint(hexStr, 16, 64)
}

// ParseDecToInt32 解析十进制字符串为int32
func ParseDecToInt32(decStr string) (int32, error) {
	val, err := strconv.ParseInt(decStr, 10, 32)
	return int32(val), err
}
